version 0.0  :  20/12/2020
rev 13/04/2022.


PIC 18F27K42 : avec LCD OLED , RTC .


*
MikroC 7.60
*
(MC Limited 2K ) avec I2C1 Hardware SANS lib MikroC : OK avec OLED ( sans RTC) rev 01/02/2021
* I2C1 Software : OK avec RTC et avec OLED) rev 06/02/2021
* I2C1 Hardware avec LIB MikroC : OK avec RTC , mais BAD avec OLED !

*
Ecriture I2C1 Hardware SANS lib MikroC ( avec OLED seul ) rev 09/02/2021
* Lecture/Ecriture I2C1 Hardware SANS lib MikroC ( avec RTC et OLED) rev 06/03/2021
.............+ version avec fichiers séparés pour OLED et RTC



*MPLABX + XC8
I2C1 Hardware (OLED 0,96" ou Mini_OLED
I2C1 Hardware .. suite avec 2 types de LCD OLED + RTC DS3231 + UART RX interrupt)



NECTO STUDIO MikroC AI I2C Hardware .. à suivre



LCD Mini OLED (40x12mm) grafique 128x32
Test avec I2C1 Hardware PIC 18F27K42
et MikroC


Hardware :

IIC I2C 0.91"128x32 Bleu OLED LCD Display Module 3.3 V 5 V coût < 2,50€ !
Plus de Details ICI

Pin Description:
GND: Power Ground
VCC: Power + (DC 3.6 à 5v)
SCL: Clock Line
SDA: Data Line
Nota :
pas de pins pour configurer une autre adresse I2C que 0x78 !
dommage, on ne peut pas en mettre plusieurs sur le meme bus I2C
pour ce PIC, on travaille avec l'adresse device sur 7 bits , soit @0x3C.

Base 18F27K42
* liaison I2C1 SDA SCL
* liaison UART1 ---TX,RX ---prolific cable _USB-- YAT terminal PC
Alimentation via un bloc secteur 9V DC -- Regulateur DC/DC LM2906--ajustable à 3.6V
* Liaisons SQA Analyser sur bus I2C1 , RA3 pour trigger, et RA6 Clkcout

images/t_Base_18F27K42_Mini_OLED_Test_202012.gif
prototype de test sur BASE 18F27K42


Le controleur LCD est basé sur un SSD1306 .
La librairie :
OLED_132x28_I2C1_1911.mcl

Voir le header pour la liste des differentes fonctions possibles.
Le point clé est l'INITIALISATION correcte du LCD
La GROSSE DIFFERENCE :
Seules les 2 fonctions de base Write_Cmd et Write_Data sont specifiques au 1827K42
car ,sur ce PIC, l' I2C hardware est un module à part entiere, non semblable au MSSP
utilisé en I2C sur les pics précédents tel le 18F26K22 !

Au demarrage du programme ...apres l'init de l'I2C,
On vérifie la presence du device LCD OLED via son adresse device sur 7 bits !
ici adresse -7bits) I2C device trouvé = 60 soit 0x3C

L'analyser SQA50 montre que le LCD OLED est bien detecté sur le bus I2C1 Hardware
via le "ACK"
Mais quid du PIC present de 340nS ?

images/t_Oled_I2C_detected.gif

A noter au passage : la sortie CLKOUT (en rouge) à 16MHz !

Puis on lance l'init du LCD OLED
et 1er test d'affichage

RIEN SUR LE LCD !


Programme :

Mikro C 7.60:
pour info:
projet en version I2C1 Hardware MikroC ( non opérationnel !)
last update : 21/12/2020
PIC18F27K42_UART1_ADC_I2C_Hardw_mini_OLDED_40x10mm_SSD1306_Test_2020_1221.zip
Pas glop avec le LCD OLED ,
Serait-ce parce que le LCD OLED SSD1306 ne contient pas de registres .. comme d'autres circuit I2C (ex RTC DS3231, PCF8754..)






Programme en version MikroC 7.60 limited 2K:
projet en version I2C1 Hardware SANS Librairie I2C Hw MikroC ( OK !)
last update : 01/02/2021

I2C1 Hardware fonctions Ecriture , by Satinas ,
voir (
Forum FantasPic)

Programme minimaliste
Pour pouvoir utiliser un écran mini OLED SD1306 de 128x32 25mmx10mm ,
Initialiser l' OLED completement
Effacement , remplissage écran
afficher 21 caracteres en fonte 6x8 : de A ....Q
Afficher 2 Big characteres '0' et '1' en fonte de 16x24
Les tailles de fontes sont réduites au minimum pour que le code ne depasse pas 2048 bytes
de la version d'essai MikroC

//const unsigned char font_regular_6x8[96][6] = {
unsigned char font_regular_6x8[17][6] = {
// 102 bytes
unsigned char * Big_Numbers[] = { chiffre0, chiffre1 }; // limité à 2 chiffres seulement

Used RAM (bytes): 355 (4%) Free RAM (bytes): 7815 (96%)
Used ROM (bytes): 1974 (2%) Free ROM (bytes): 129098 (98%)


usage de MPLABX IPE V5.30 + Pickit4
Loading code from C:\_MikroC\_MesProjets_MikroC\_2tsts\18F27K42_Oled_Big_Satinas\
Test_Oled_Big_18F27K42_Satinas_2021.hex...
2021-02-01 13:16:12 +0100 - Hex file(s) loaded successfully.
2021-02-01 13:16:13 +0100
- Programming...
*************
Calculating memory ranges for operation...
Erasing...
The following memory area(s) will be programmed:
program memory: start address = 0x0, end address = 0x7ff
configuration memory
User Id Memory
Programming/Verify complete
2021-02-01 13:16:22 +0100 - Programming complete


Projet MikroC :
Test_Oled_Big_18F27K42_Satinas_2021.mcppi
18F27K42_Oled_Big_Satinas_MikroC_limited_2021.zip
Test_Oled_Big_18F27K42_Satinas_2021_MikroC_Limited.hex
Test_BigChar_18F27K42_by_Satinas_2021_0201.c
Test_Oled_Big_18F27K42_Satinas_2021.cfg
18F27K42_Fosc_interne_32Mhz.cfgsch
Oled register names : ssd1306.h





Programme en version MikroC 7.60 (Full=enregistrée) :
projet I2C1 Hardware SANS Librairie I2C1 Hw MikroC
last update : 09/02/2021
phase 1 : gestion mini OLED I2C1 seul

Avec toutes les fonctionalités de la version OLED MikroC I2C Software .. mais utilise ici le I2C1 HARDWARE SANS la lib MikroC
en fonction ECRITURE seulement !

Fonctions liées à l'usage de L'OLED LCD 128x32:

void I2C1_hw_Init(void);
unsigned char I2cScan(void) ; // Scan bus I2C, envoi Start + adresse + Stop
void My_OLED_Init(void); // SSD1306.pdf
void WriteDat(unsigned char I2C_Dat);
void OLED_Cde(unsigned char c);
void OLED_Data(unsigned char *p1, unsigned char nb);
void Big_affichage( unsigned char posX, unsigned char N );
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char *ch, unsigned char TextSize);
void OLED_DrawBMP(unsigned char x0,unsigned char page0,unsigned char x1,unsigned char page1,const unsigned char *BM);
void OLED_DrawBMP_128x32(const unsigned char *BM);
void Resize();
void OLED_Fill(unsigned char ca);
void OLED_CLS(void);
void OLED_SetPos(unsigned char x1, unsigned char y1);
void Write_Char_At(unsigned char X,unsigned char Y, unsigned char C);
void OLED_Pixel(unsigned char x, unsigned char y,unsigned char Color);
void Draw_Line(unsigned char x1, unsigned char y1, unsigned char x2, signed char y2, unsigned char color);
void Draw_Triangle(unsigned char x0, unsigned char y0, unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, char color);
void Draw_Rectangle(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char fill, unsigned char colour);
void Draw_Circle(unsigned char xc, unsigned char yc, unsigned char radius, unsigned char fill, unsigned char colour);
void Refresh_OLED(void) ; // to see RamBuffer content
void Raz_RamBuffer(void) ; // size 128 x 4 pages=512
void ShowBigNumber(unsigned char x,unsigned char y, unsigned char N) ; //16x16
void Affiche_Car_8x8 ( unsigned char posX, unsigned char PosY, char *Name );
//const unsigned char points ...fleche_bas,fleche_haut,_degre,DegreC,moins
void Affiche_Car_Speciaux_8x8( unsigned char posX, unsigned char PosY, char Num );




Projet MikroC :
PIC18F27K42_UART1_ADC_RTC_mini_OLED_25x10mm_LCD_I2C1_Softw_Test_2021_02.mcppi
18F27K42_UART1_ADC1_Mini_Oled_20x10mm_RTC_I2C_Hw_SANS_MC_lib_2021_0209.zip
P18F27K42_I2C1_HW_mini_OLED_128x32_sans_MC_Lib_2021_0209.hex
OLED_128x32_Tables_2021_02.h
P18F27K42_I2C1_HW_mini_OLED_128x32_sans_MC_Lib_2021.cfg
P18F27K42_Fosc_Interne_64Mhz_with_RA6_Clockout.cfgsch
BMP_images_128x32_2021-0207.inc




PHASE 2 : OLED et Intégration RTC DS 3231
(Pilotage en I2C1 Hardware
SANS Librairies: I2C1 Hw, ni UART, ni PPS MikroC)
last update : 06/03/2021


Prototype de test , sur BASE 18F27K42 :
Alim 3,6V DC
Liaison UART via Prolific cable USB <-> PC terminal YAT
Liaison ICSP au Pickit4 <-> MPLABX IPE V5.30
Liaison I2C1 RC3-RC4 <--> module RTC DS3231+eeprom
Liaison I2C1 RC3-RC4 <--> mini LCD OLED
option : strap momentané RC0 pour forcage RTC
option : strap momentané RC1 pour decouverte des devices I2C
Led sur sortie SQW 1Hz de la RTC .(temoin de bon fonctionnement)
Led sur RA4 (temoin cycle boucle principale)

images/t_Proto_18F27K42_UART1_ADC1_Mini_Oled_20x10mm_RTC_I2C_Hw_SANS_MC_lib_2021.gif
images/t_P18F27K42_I2C1_HW_OLED_128x32_RTC_sans_MC_Lib_2021_03_Running.gif

écran au démarrage

Cette fois , rajout de la fonction LECTURE (Read) I2C pour lire les registres :Date Time de la RTC
Deux façon de lire les registres RTC, soit :
*par pooling du bit d'état I2C1STAT1_RXBF ,
*par interrupt via le bit I2C1RXIF

if ((I2C1RXIF_bit==1) && (I2C1IE_bit==1)&& (PIE2_I2C1RXIE ==1) )
{
*(p1++)=I2C1RXB;
I2C1RXIF_bit=0;
}

coté transmission, Ecriture, dans les registres RTC , soit :
*par pooling du bit d'état I2C1STAT1_TXBF ,
*par interrupt via le bit I2C1TXIF
if ((I2C1TXIF_bit==1) && (I2C1IE_bit==1)&& (I2C1TXIE_bit ==1) )
{
I2C1TXB=*(p1++);
I2C1TXIF_bit=0;
}
}


Le programme gère aussi , l' UART1 Hw Sans la lib UART MikroC, ni la lib PPS MikroC
La gestion interrupt UART RX , permet la mise à jour de la RTC .
sinon, l'UART est surtout utilisé comme Traceur/debugger de programme

L'application commence par faire l'init Specifique I2C1 Hardware en s'appuyant sur une définition séparée
des registres I2C1 18F27K42, car tous ne sont PAS DISPONIBLES sous MikroC



la config Hardware des pins I2C et UART se passe sans l'usage de la lib PPS, qui gaspille 1580 bytes !
L'UART est configuré aussi , via ses registres.. à 19200,8,N,1 pour FOSC interne MCU=64MHz
La pin RC1=0 permet d'activer la découverte des devices sur le BUS I2C1.
Test presence device(s) sur le bus I2C1 avec RC1=0
Device(s) trouvés sur le bus
Device #1 at @78
Device #2 at @AE
Device #3 at @D0

Adresse utilisée sur 8 bits : 7 bits @device + bitR/W

La pin RC0=0 permet de faire une premiere init RTC ( RTC vierge ou apres changement de Pile)
Init RTC Forcee à samedi 02/03/21 18:46:57 via RC0=0
Lecture et affichage individuel des 7 Registres DS3231
Registre #0 57
Registre #1 16
Registre #2 18
Registre #3 06
Registre #4 02
Registre #5 03
Registre #6 21
Registre #7 00

sinon, la RTC est simplement relue ..pour remplir les champs Date et heure.
ensuite :
init (avancée) de l'ADC 12bits Voie EA1 ( ici avec +VRef=VCC et -VREF=Gnd) soit gamme de mesure =3.6V=VCC
Init de l'OLED SSD1306 en mode 4 pages 128x32
Un buffer RAM de 512 bytes est utilisé pour pouvoir mixer Texte et Graphisme.
Les diffeéentes fontes de caractere sont en Flash ROM , taille 5x7 , 8x8 , et 16x32.
La fonte est choisie en fonction de la taille du texte :1,2, ou 3
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char *ch, unsigned char TextSize)
un caractere 16x32 est defini par 48 bytes !, char uniquement numérique ( 0 à 9)+ speciaux : Point décimal , Degré , Moins, et Espace.

La principale fonction pour la RTC est :
void Display_Date_Time(char Visu)
{ unsigned char Adresse,Registre;
signed char Nb;
int i;
Adresse=DS3231_ADDR;
Registre=0;
Nb=7;

for(i=0;i<8;i++) tmp[i]=0;
p1=&tmp[0];
DS3231_Read_All_Registers();
time[0]=0;
date[0]=0;
BCD_To_Ascii(heure,time) ; time[2]='H';
BCD_To_Ascii(minute,time+3 ); time[5]='M';
BCD_To_Ascii(second,time+6); time[8]='S';time[9]=0;
BCD_To_Ascii(jour,date); date[2]='/';
BCD_To_Ascii(mois,date+3); date[5]='/';
BCD_To_Ascii(Annee,date+6); date[8]=0;
Month=Bcd2Dec(mois);
Sec= Bcd2Dec(second);
if( Visu==1)
{ Print(date); CPrint(Blancs);
Print(time); CPrint(Blancs);
}
}

Le parametre visu=1 affiche la date et heure sur le terminal (UART)
la fonction DS3231_Read_All_Registers(); recupere les 7 parametres essentiels de la RTC
le mode interruption est utilisé .. on laisse l'interrupt remplir le buffer de lecture.

Via l'UART on peut envoyer une demande de Mise A Jour (MAJ) RTC .
suivant un format que j'utilise pour toutes mes applis ( et celles en Android / Bluetooth)
Nota:
le parametre JS jour de la semaine , en position 4 dans la RTC , est transposé à la fin, pour etre compliant avec
Appinventor II Android et le format date.

L'envoi de la commande Help .. le rappelle
Help Commandes :
MAJ RTC
ex: U;03;03;21;15;14;03;# pour 03 mars 2021 , 15H14 Mercredi

exemple de MAJ :
nota: le mode interruption RX UART , permet de recevoir la commande ,malgre le flux d'infos envoyé par l'UART

Affichage Rectangle Triangle Cercle
02/03/21 18H34M07S ; ;E= 2671 2.35°C ...
Avant
Affichage sinusoide

U;06;03;21;17;45;06;# ...
la commande

MAJ RTC
U;06;03;21;17;45;06;
.. acceptée
Index1 = 21
06 03 21 17 45 06
Jour Semaine jS = 6 Samedi mois =Mars
param Ok
Ecriture en bloc dans DS3231... OK
...transférée
Write 6 car.speciaux
18.75°C
Affichage Rectangle Triangle Cercle
06/03/21 17H40M09S ; ;E= 2682 2.36°C
... MAJ OK

La valeur de la temperature (capteur interne RTC) est aussi capturée via les registres 0x11 et 0x12 de celle ci
puis affichée sur terminal et LCD OLED
Ds3231_Temp_CP(1); // 0=pour UART 1=pour LCD ou OLED

Le programme, apres les phases d'init, affiche quelques possibilités Graphiques de ce LCD OLED (voir version OLED seul)
entre dans la boucle principale .
un "switch case " permet de changer l'affichage toutes les 2 secondes environ.
un delay (neutre, sans IT) de 1sec est introduit dans la boucle pour permettre une meilleur réactivité de la reception UART.
1) Heure et date RTC + valeur Entree ANA en point et en flotant ( en taille 2)
2)Affiche une sinusoide graphique + texte persistant .
3)Affiche 6 caracteres speciaux (non ascii), definis à part ( voir OLED_128x32_Tables_2021_03.h)
4)Affichage la temperature interne RTC, valeur en Taille 3)
5) Affiche 3 figures geometrique Carré, Triangle ,Cercle

Video :
P18F27K42_UART1_ADC1_Mini_Oled_20x10mm_RTC_I2C_Hw_SANS_MC_lib_2021_T.webm

...et le log terminal

Le programme MikroC 7.60


Projet complet : P18F27K42_I2C1_HW_mini_OLED_128x32_et_RTC_sans_MC_Lib_2021_0308.zip
Projet : P18F27K42_UART1_I2C1_HW_OLED_128x32_RTC_ALL_in_One_sans_MC_Lib_2021_0307.mcppi
Source : P18F27K42_I2C1_HW_RTC_OLED_sans_MC_Lib_2021_0307_All.c 1 seul fichier contenant aussi les sources OLED et RTC
Fontes : OLED_128x32_Tables_2021_03.h
Tables Images BMP : BMP_images_128x32_2021-03.inc
chargeur: P18F27K42_UART1_I2C1_HW_OLED_128x32_RTC_ALL_in_One_sans_MC_Lib_2021_0307.hex

petite modif :
void Print_Date_Complete(void)
{
DS3231_Read_All_Registers();
time[0]=0;
BCD_To_Ascii(jour,date); date[2]='/';
BCD_To_Ascii(mois,date+3); date[5]='/';
BCD_To_Ascii(Annee,date+6); date[8]=0;

CPrint(JourSemaine[jS]);Envoi_Char(' ');
BCD_To_Ascii(jour,CRam1);Print (CRam1);Envoi_Char(' ');
Month=Bcd2Dec(mois);
CPrint(Douze_Mois[Month]);Envoi_Char(' ');
BCD_To_Ascii(Annee,CRam1);Print (CRam1);Envoi_Char(' ');

BCD_To_Ascii(heure,time) ; time[2]='H';
BCD_To_Ascii(minute,time+3 ); time[5]='M';
BCD_To_Ascii(second,time+6); time[8]='S';time[9]=0;
Print(time);
CRLF1();
}
=> affiche sur OLED : 07/03 15H29M15
=> affiche sur terminal : Dimanche 07 Avril 21 15H29M15S


Nota : on peut en rajouter pas mal !car il y a de la place dans ce PIC !
Used RAM (bytes): 1364 (17%) Free RAM (bytes): 6806 (83%)
Used ROM (bytes): 28888 (22%) Free ROM (bytes): 102184 (78%)

En conclusion :
Verification des librairies MikroC utilisées:

_Lib_Math.mcl" "
_Lib_MathDouble.mcl" "
_Lib_System.mcl" "
_Lib_Delays.mcl" "
_Lib_CType.mcl" "
_Lib_CString.mcl" "
_Lib_CStdlib.mcl" "
_Lib_Conversions.mcl" "
_Lib_Sprintf.mcl" "
_Lib_ADC_K40.mcl"

ça a été laborieux, mais Le but final est atteint :
car pas de Lib concernant L'UART1, ni de I2C1 , ni PPS (tres gourmande en taille : 1582 bytes!)
* Merci à Satinas pour son aide et collaboration.
.....et toujours aucun retour support MikroE à ce jour ..Tant pis pour eux, on peut s'en passer maintenant.




Version avec fichiers separés pour la gestion RTC et OLED :


Projet complet : P18F27K42_I2C1_HW_mini_OLED_128x32_et_RTC_sans_MC_Lib_2021-0308_avec_Oled_RTC_inc.zip
Source principale : P18F27K42_I2C1_HW_RTC_OLED_sans_MC_Lib_2021_0308.c
gestion OLED : OLED_mini_2021-0308.inc
gestion RTC : RTC_DS3231_2021-0308.inc
Chargeur : P18F27K42_I2C1_HW_mini_OLED_128x32_et_RTC_sans_MC_Lib_2021-0308.hex
Compilation selective , Avec ou sans OLED ou RTC
La base I2C1 Hw reste dispo dans la source principale.







Programme Mini-OLED MikroC en version I2C1 SOFTWARE (18F27K42)
rev 05/02/2021

projet Mikro C 7.60: (OK !)

Avec ADC1 (12bits) , et RTC DS3231 en I2C1 software (Librairie MC).

Le programme commence par l'init de L'UART, puis la decouverte des devices sur le bus I2C
Device(s) trouvés sur le bus
Device #1 at @78 <--- le LCD OLED adresse device + bit R/W sur 8 bits
Device #2 at @AE <--- l'EEPROM sur le module carte RTC
Device #3 at @D0 <--- la RTC DS3231

Une boucle d'attente sur Evenement ( Touche clavier) ou Timeout (via Timer0)
permet de sequencer le déroulement du programme

L'affichage sur ce LCD :
permet plusieurs taille d'affichage des caracteres
jusqu'à 21 chars par ligne ( fonte en 5x8 avec 1 pixel intercaractere)
ou 16 chars en taille 2
ou 8 chars en taille 3
ou Big Charactere 16x24
ou de 4 caracteres speciaux (personalisés , en 8x8 )
// caraters speciaux , attention RESPECTER la case ( majuscule/minusules)
#define Point 0
#define Fleche_Bas 1
#define Fleche_Haut 2
#define Degre 3



Affichages Graphiques :
Pixels
Lignes
Rectangles
Cercles
Sinusoide
images BMP limitée à 128x32 pixels
Mixage Texte et Graphique possible


L'horloge RTC est initialisée par defaut à la date du "01 mai 2018 15H59" si RB1 est à 1
sinon, avec RB1=0, la RTC est relue .
L'entree Analogique RA1 (12 bits) est scrutée à chaque tour de boucle principale( 1sec, cadencé par TMR0 interrupt),
puis moyenné toutes les 8 mesures.
Affichage sur LCD de la valeur en points et de la valeur en Volts
gamme 0 à VCC=3.6V pour 0 à 4095 pts

images/Project_manager_18F27K42_UART1_ADC1_Mini_Oled_et_RTC_I2C_Soft_20x10mm_MCL_2021.jpg

librairie : Mini_OLED_128x32_I2C1_Softw_18Fx7K42_2021.h

// 05-02-2021
# #define OLED_ADDRESS 0x78
void setColAddress(void);
void setPageAddress(void);
void WriteCmd(unsigned char I2C_Cde);
void WriteDat(unsigned char I2C_Dat);
void OLED_Init(void);
void OLED_SetPos(unsigned char x, unsigned char y);
void OLED_Fill(unsigned char fill_Data);
void OLED_CLS(void);
void OLED_ON(void);
void OLED_OFF(void);
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char *c, unsigned char TextSize);
//void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N); // chinese Carac
void init_OLED(void);
void OLED_initialise(void);
void Write_Char_At(unsigned char X,unsigned char Y, unsigned char C);
void OLED_DrawBMP_128x32(const unsigned char *BM);
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,const unsigned char *PP);
void printBigNumber(char st, int X, int Y);
void Decompile_byte(unsigned char un);
void OLED_pixel(short x, short y, char color);
void Refresh_OLED(void) ;
//void ShowBigNumber(unsigned char x, unsigned char y, unsigned char N);
void Big_affichage( unsigned char posX,unsigned char N);
void Affiche_Car_Special_8x8 ( unsigned char posX, unsigned char PosY,unsigned char N );
void OLED_BMP_Chek_on_Terminal(const unsigned char *BM);
void OLED_Draw_Pixel(unsigned char x, unsigned char y,unsigned char Color);
void Draw_Pixel(unsigned char x, unsigned char y,unsigned char Color);
void Draw_Pixel_(unsigned char x_pos, unsigned char y_pos, unsigned char colour);
void Draw_Rectangle(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char fill, unsigned char colour);
void Draw_Line(unsigned char x1, unsigned char y1, unsigned char x2, signed char y2, unsigned char color);
void Draw_Circle(unsigned char xc, unsigned char yc, unsigned char radius, unsigned char fill, unsigned char colour);
void OLed_Shift_Droit(int n1, int t1);
void RAZ_Ram_Buffer(void);

Compilation et chargement dans le PIC

MPLAB IPE 5.30 + Pickit4 en mode MPLABLoading
Loading code from C:\_MikroC\_MesProjets_MikroC\_18F27K42_UART1_ADC1_Mini_Oled_et_RTC_I2C_Soft_20x10mm_2021\
PIC18F27K42_UART1_ADC_RTC_mini_OLED_25x10mm_LCD_I2C1_Softw_Test_2021_02.hex...
2021-02-05 19:05:10 +0100 - Hex file loaded successfully.
2021-02-05 19:05:10 +0100 - Programming...
*****************************************************
Calculating memory ranges for operation...
Erasing...
The following memory area(s) will be programmed:
program memory: start address = 0x0, end address = 0xa47f
configuration memory
User Id Memory
Programming/Verify complete
2021-02-05 19:05:21 +0100 - Programming completete



Projet : _18F27K42_UART1_ADC1_Mini_Oled_et_RTC_I2C_Soft_20x10mm_2021_02_07.zip
Source : PIC18F27K42_UART1_ADC_I2C1_SOFTw_mini_OLDED_25x10mm_SSD1306_RTC_DS3231_Test_2021_0207.c
Tiny_RTC_DS3231_I2C_Softw_for_AI2_2021_02.c
Librairie OLED :
Mini_OLED_128x32_I2C1_Softw_18F27K42_2021_02.mcl
Mini_OLED_128x32_I2C1_Softw_18F27K42_2021_02.c

Header lib : Mini_OLED_128x32_I2C1_Softw_18Fx7K42_2021_02.h
Librairie RTC :
Tiny_RTC_DS3231_I2C_Softw_for_AI2_2021_02.mcl
Tiny_RTC_DS3231_I2C_Softw_for_AI2_2021_02.c
Header lib : Tiny_RTC_DS3231_I2C_Softw_for_AI2_2021_02.h
Chargeur : PIC18F27K42_UART1_ADC_RTC_mini_OLED_25x10mm_LCD_I2C1_Softw_Test_2021_0207.hex

Images BMP :
BMP_images_128x32_2021-0207.inc


Terminal capture:


détails:
YAT-Log-20210207-135432.log


Ecrans OLED :

taille 1 taille 2 taille 3



..OK ,en mode I2C Software

Video :
Test_Mini_OLED_128x32_MC_I2CSoft_18F27K42_2021_0208.webm





LCD Mini OLED (40x12mm) grafique 128x32
avec PIC 18F27K42
et MPLABX XC8
avec I2C1 HARDWARE

Programme:

last update : 31/12/2020
projet actuel ....OK !
.. apres maintes peripéties !!!!!

HARDWARE

Alimentation VCC= 3.6V
Carte BASE 18F27K42
Entree Analogue sur RA1 : 0 à 3,6V sur 12 bits !
UART1 TX sur RC6
NCO1 sortie 10KHz sur output RA3
sortie FOSC/4=16Mhz sur output RA6
Synchro SQA analyser sur sortie RC5

Capture trame I2C1 au debut de l'init OLED :

images/t_Mini_OLED_I2C_Hardware_Init_SQA_2020_1231.gif

Avec une fonte de 5x8 , avec 1 pixel entre caracteres, on obtient 128/(5+1)=21 characteres par lignes
et donc 32/8= 4 lignes ..
Une ligne est representée par un Numero de page: 0 à 3

void OLED_WriteCharacter(unsigned char character)
{ int i,k;
k=(character - 0x20)*5;
for (i=0; i<5; i++) OLED_Donnee(Fonte[k+i]);
OLED_Donnee(0x00); // ==> 6x8 128/6=> 21 car/ligne
// OLED_Donnee(0x00); // ==> 7x8 128/7=> 18 car/ligne
// OLED_Donnee(0x00); // ==> 8x8 128/6=> 16 car/ligne
}


ATTENTION : L' init du LCD SSD1306 est tres POINTILLEUSE !

void OLED_Init(void)
{
//SSD1306.pdf
//Software Configuration 31/12/2020 OK avec mini_OLED 20x10mm

OLED_Cde(0xAE); //display off
__delay_ms(5);
OLED_Cde(0xAF); //display on
__delay_ms(5);
OLED_Cde(0xB0);// Set GDDRAM Page start adresse [2:0] 0 à 7
OLED_Cde(0x00); // mini 0
OLED_Cde(0x03); // maxi
// OLED_Cde(0x07); // maxi pour 128x64
OLED_Cde(0x20); //Set Horizontal Memory Addressing Mode
//A[1:0] = 00b, Horizontal Addressing Mode
//A[1:0] = 01b, Vertical Addressing Mode
//A[1:0] = 10b, Page Addressing Mode (RESET)
//A[1:0] = 11b, Invalid
OLED_Cde(0x02); // Page Addressing Mode (RESET)
OLED_Cde(0x21); // Setup column start and end address
OLED_Cde(0); //A[6:0] : Column start address, range : 0-127d,(RESET=0d)
OLED_Cde(0x7F); // B[6:0]: Column end address, range : 0-127d,(RESET =127d)
OLED_Cde(0x22);// Setup page start and end address
// A[2:0] : Page start Address, range : 0-7d,
// (RESET = 0d)
// B[2:0] : Page end Address, range : 0-7d,
// (RESET = 7d)
OLED_Cde(0x00);
OLED_Cde(0x03); //was 0x07
// OLED_Cde(0xA0); //--set segment re-map colum 0 to SEG 0 de droite -> gauche
OLED_Cde(0xA1); //--set segment re-map to 127 de gauche -> droite
OLED_Cde(0xA4);//command enable display outputs according to the GDDRAM contents.
// OLED_Cde(0xA5);//command forces the entire display to be ?ON?, regardless of the contents of the display data RAM.
OLED_Cde(0xA6);//normal display
// OLED_Cde(0xA7);//reverse display
OLED_Cde(0xC8); //Set COM Output Scan Direction
//C0h, X[3]=0b: normal mode (RESET) Scan from COM0 to COM[N ?1]
//C8h, X[3]=1b: remapped mode. Scan from COM[N-1] to COM0
OLED_Cde(0xD3); //--set start line address 40h = set to 0
// OLED_Cde(0x40); // ou 0x3F
OLED_Cde(0x3F);
// was OLED_Cde(0x00);
//0xD3,0x3F, // DISPLAY offset ROW0 - L0xD3,0x00,leaves one row of pixels at top. 0xD3,0x3F is better
OLED_Cde(0xD5); //--set display clock divide ratio/oscillator frequency
OLED_Cde(0x80); //--set divide ratio 80h
OLED_Cde(0xA8); //--set multiplex ratio to 63
OLED_Cde(0x3F); // was 3F
OLED_Cde(0xD6); //-- This command is to set the vcommon signals padconfiguration.
OLED_Cde(0x80); // --set divide ratio 80h
OLED_Cde(0xD9); //--set display clock divide ratio/oscillator frequency
// A[3:0] : Phase 1 period of up to 15 DCLK clocks 0 is invalid entry(RESET=2h)
// A[7:4] : Phase 2 period of up to 15 DCLKclocks 0 is invalid entry(RESET=2h )
OLED_Cde(0x1F); // 22h --reset values 22h
// OLED_Cde(0x1F); // 44h --reset values 22h
//0xDA, (C.OLED_HEIGHT==64)?0x12:0x02,
OLED_Cde(0xDA); //--set com pins hardware configuration
OLED_Cde(0x20); // was 0x02 32
// OLED_Cde(0x00); // was 0x02 32
// OLED_Cde(0x12); // 0x12h 64
// A[4]=0b, Sequential COM pin configuration
// A[4]=1b(RESET), Alternative COM pin configuration
// A[5]=0b(RESET), Disable COM Left/Right remap
// A[5]=1b, Enable COM Left/Right remap
// OLED_Cde(0xE0); // Read-Modify-Write start
OLED_Cde(0xEE); // Read-Modify-Write end.
OLED_Cde(0x81); //--set contrast control register
OLED_Cde(0x7F); // 0x00~0xff
OLED_Cde(0x2E); // no scrolling
OLED_Cde(0xDB); //--set VComH deselect level
// OLED_Cde(0x35); //--POR =35h
OLED_Cde(0x40); // 20H => 0.77x Vcc (Reset value)
OLED_Cde(0x8D); //--set DC-DC enable Charge Pump Setting
OLED_Cde(0x14); // 0x14 Enable Charge Pump
OLED_Cde(0xAF); //--turn on oled panel
}

Affichage sur Terminal :

(0.000) ABCDEF
(0.020)
(0.007)
(0.000) Projet MPLABX : _18F27K42_mini_OLED_20x10mm_SSD1306.X
(0.025) Compile le Jan 02 2021 a 11:00:35 UTC
(0.023) avec version XC8 : 2100
(0.012) Usage de OLED_SSD1306_I2C_Hardw_18Fx7K42_2021.c rev 02/01/20201
(0.049) Hardware : BASE 18F27K42
(0.000) Entree ANA sur RA1
(0.036) Sortie NCO1 10Khz sur RA3
(0.000) SQA50 synchro Analyser : Sortie sur RC5
(2.003) Init mini-OLED SSD1306 20x10mm I2C1 Hardware avec OLED_Init
(0.054) 4 lignes de 128/6=21 chars avec fonte 5x8
(0.311) Clear OLED
(0.381) 123456789012345678901
(1.072) MCU 18F27K42 I2C HW EA1=3988 soit 3.505V
(2.143) MCU 18F27K42 I2C HW EA1=3988 soit 3.505V
(2.143) MCU 18F27K42 I2C HW EA1=3988 soit 3.505V
(2.143) MCU 18F27K42 I2C HW EA1=3988 soit 3.505V
(2.143) MCU 18F27K42 I2C HW EA1=3980 soit 3.498V
(2.143) MCU 18F27K42 I2C HW EA1=3988 soit 3.505V


Les Ecrans obtenus :
sont les memes que dans la version MikroC I2C Software ( encore heureux !)

taille mini 21 chars par ligne (4 lignes maxi) image BMP


Programme:

last update : 02/01/2020
projet actuel ....OK !

18F27K42_mini_OLED_20x10mm_SSD1306_2021_XC8.zip
main : main_for_OLED_SSD1306_I2C_Hardw_18Fx7K42_2021.c
Oled lib source :
OLED_SSD1306_I2C_Hardw_18Fx7K42_2021.c
Oled Header :
OLED_SSD1306_I2C_Hardw_18Fx7K42_2021.h
Chargeur :
18F27K42_mini_OLED_20x10mm_SSD1306_XC8_2021.hex
Fontes :
Fontes_for_OLED.h




Phase 2 (MPLABX) :
Intégration RTC DS3231 I2C1 HW et UART1 RX interrupt
19/03/2021
suite de la
précedente version ......

Rajout du choix de gestion de 2 types d'écrans ,
OLED 0,96"" 128x32 Jaune/bleu ou Mini-OLED sur I2C1 via l' état de la Pin RB1
RTC DS3231 sur bus I2C1 ( RC3=SCL RC4=SDA)
Forçage Init Date et Heure RTC via pin RC0.
UART1 TX=RC6 RX=RC7
Analog sur RA1
Gestion RX Interrupt pour pouvoir faire la Mise A Jour RTC

MCC Pin designer Project MPLABX XC8

Hardware :

images/t_Hardware_18F27K42_OLED_SSD1306_RTC_UART_ITRX_2021-03.gif

Les 2 OLEDs sont tous deux sur le bus I2C1
mais 1 seul est activé (normalement)
Run du programme AVEC choix de type OLED via RB1=0 et RB1=1

Le choix est fait au lancement programme, dans le main.c :

CPrint(" Choix du type LCD OLED via etat Pin RB1 =");
putch((PORTB & 0x02)+48);
CRLF1();
if (Choix_OLED_096==1) // RB1 input=1
{
CPrint(" OLED 096"" SSD1306 24mm x 28mm I2C1 Hardware\r\n");
}
else
{
CPrint(" mini-OLED SSD1306 20 x 10mm \r\n");
}


L'init OLED , void OLED_Init(void)
est modifée suivant la valeur de Choix_OLED_096 (RB1), en 3 endroits :
Les 2 OLEDS sont traités en 128x32 , 4 Pages ..

if (Choix_OLED_096==1)
OLED_Cde(0x02); //A[1:0] = 10b, Page Addressing Mode (RESET)
else
OLED_Cde(0x00); ////A[1:0] = 00b, Horizontal Addressing Mode

if (Choix_OLED_096==1) // modele OLED avec 1Ligne jaune + 3 lignes Bleues
OLED_Cde(0x40); //--set start line address 40h | xx avec xx=0
else
OLED_Cde(0x00);



OLED_Cde(0xDA); //--set com pins hardware configuration
if (Choix_OLED_096==1)
OLED_Cde(0x00); //--set start line address 40h | xx avec xx=0
else
OLED_Cde(0x20); // was 0x20




images/t_Run_MPLABX_18F27K42_OLED_SSD1306_RTC_UART_ITRX_2021-03.gif

Difficulté rencontrée :
Traitement RX Interrupt trop "pre-maché " par MCC
ce qui rend difficile la Personalisation ...
Peut-etre aurais-je dû NE PAS EMPLOYER MCC ..

Le traitement Présence Device (100% hardware register) ne marchait pas ..
malgré les ressources I2C1 HW initialisées
Modifs nécessaires :
I2C1CON2bits.ABD=0; // ADB=0; // Transmitted address data is loaded from the I2CxADB0/1 registers.
I2C1CON0bits.EN = 1;
A noter , au passage ,le rajout en clair de certain devices reconnus ..

txt=&TEXTE[0];
*(txt)=0;
CRLF1();
CPrint(" Test Presence I2C device (adressage 8 bits)\r\n");
I2C1CON2bits.ABD=0; // ADB=0; // Transmitted address data is loaded from the I2CxADB0/1 registers.
I2C1CON0bits.EN = 1;
for (i=2; i<=253; i=i+2)
{
if (I2C1_DevicePresent(i))
{
k=i>>1;
sprintf(txt," @ decimal #%4u soit @Device7bits = 0X%02X ",i,k);
switch (k)
{
case 0x27:
case 0x28:
case 0x29:
case 0x2A:
// case etc ..
strcat(txt,"PCF8574 8bits I/O");// de base + 7 autres
break;
case 0x37:
strcat(txt,"LCD 2119 2x16cars"); // de base + 7 autres
break;
case 0x38:
case 0x39:
case 0x3A:
case 0x3B:
// case etc ..
strcat(txt,"PCF8574A 8bits I/O"); // de base + 7 autres
break;
case 0x3C:
strcat(txt,"OLED SSD1306");
break;
case 0x53:
strcat(txt,"ADXL345 board");
break;
case 0x57:
strcat(txt,"EEPROM 512bytes");
break;
case 0x68:
strcat(txt,"RTC DS3231");
break;
default:
strcat(txt,"non recensé");
break;
}
Print(txt);CRLF1();
}
}
I2C1CON0bits.EN = 0;
I2C1CON2bits.ABD=1;
CRLF1();

le coeur du test :

// rev 22/03/2021
bool I2C1_DevicePresent(int16_t address)
{
I2C1PIRbits.PCIF = 0; // clear STOP bit flag
I2C1ADB1 = address; // load slave addr and R/W
I2C1CNT = 0;
I2C1CON0bits.S = 1; // send START + addr
while (I2C1PIRbits.PCIF == 0); // wait for STOP
return !I2C1CON1bits.ACKSTAT;
}


avec Not bit I2C1CON1bits.ACKSTAT Vrai si Device présent;

Execution sur terminal :
Test Presence I2C device (adressage 8 bits)
@ decimal # 120 soit @Device7bits = 0X3C OLED SSD1306
@ decimal # 166 soit @Device7bits = 0X53 ADXL345 board
@ decimal # 174 soit @Device7bits = 0X57 EEPROM 512bytes
@ decimal # 208 soit @Device7bits = 0X68 RTC DS3231


Par contre l'usage des fonctions I2C HW évoluées sont bien pratiques .
Exemple Ecriture/Lecture des registre RTC, par Bloc


CPrint( " Init RTC Forcee a samedi
02/03/21 18:46:57 via RC0=0 \r\n");
tmp[0]=0x00; //start register
tmp[1]=0x57; //second
tmp[2]=0x16; //write min
tmp[3]=0x18; //write hour;
tmp[4]=0x06; ///write day of week
tmp[5]=0x02; // write date
tmp[6]=0x03; // write month
tmp[7]=0x21; // write year
tmp[8]=0x00;
SQA=1;
p1=&tmp[0];
I2C1_WriteNBytes(DS3231_ADDR,p1,8);
SQA=0;
void DS3231_Read_All_Registers()
{ int i;
//Lecture des 7 registre RTC DS3231
// RAZ table d'echange
for (i=0;i<10;i++) tmp[i]=0 ;
p1=&tmp[0]; // pointeur sur debut de table
I2C1_ReadDataBlock(DS3231_ADDR,0,p1,7);
// SQA=0;
second=tmp[0];
minute=tmp[1];
heure=tmp[2]&0x3F;
jS=tmp[3];
if (jS>7) jS=0;
jour=tmp[4];
mois=tmp[5]& 0x1F;
Annee=tmp[6];
tmp[7]=0;
tmp[8]=0;
}
1ere Init des registres RTC Re-lecture RTC


Resultat sur terminal :

images/t_YAT_MPLABX_test_OLED_RTC_IT_UART_2021-03.gif


Projet MPLABX :
22/03/2021
*
_18F27K42_OLED_SSD1306_RTC_UART_IT_RX_XC8_2021-03.zip
*chargeur :
*
_18F27K42_OLED_SSD1306_RTC_UART_ITRX_2021-03.X.hex
*Main .c :
main_for__18F27K42_OLED_SSD1306_RTC_UART_IT_RX_XC8_2021-0322.c,
*
OLED_SSD1306_I2C_Hardw_18Fx7K42_2021-0318.c
*
RTC_DS3231_2021-0318.c
*RTC_DS3231_2021-03.h
*OLED_SSD1306_I2C_Hardw_18Fx7K42_2021-03.h

paulfjujo@free.fr


../common/mylogo_CI.jpg



Retour à l'index general